From 5ee95edd623fc5503124a9b0e160924d8d6d8b5d Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Wed, 27 Apr 2005 16:06:43 +0000 Subject: [PATCH] bitkeeper revision 1.1327.2.11 (426fb893OrpBVeRpaWJ0atIxlG4Hxw) Add support for unix-domain sockets to consoles and the event server. Signed-off-by: Mike Wray --- tools/python/xen/util/console_client.py | 28 +++++++--- tools/python/xen/web/unix.py | 19 ++++--- tools/python/xen/xend/server/SrvDaemon.py | 7 +-- tools/python/xen/xend/server/console.py | 62 +++++++++++++---------- tools/python/xen/xend/server/event.py | 24 +++++---- tools/python/xen/xm/create.py | 3 +- tools/python/xen/xm/main.py | 3 +- 7 files changed, 88 insertions(+), 58 deletions(-) diff --git a/tools/python/xen/util/console_client.py b/tools/python/xen/util/console_client.py index 8bd3178eab..c0acacfad3 100644 --- a/tools/python/xen/util/console_client.py +++ b/tools/python/xen/util/console_client.py @@ -57,9 +57,18 @@ def __send_to_sock(sock): raise sys.exit(0) -def connect(host,port): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) - sock.connect((host,port)) +def connect(host, port, path=None): + # Try inet first. If 'path' is given and the error + # was connection refused, try unix-domain on 'path'. + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((host, port)) + except socket.error, err: + if (path is None) or (err[0] != errno.ECONNREFUSED): + raise + # Try unix-domain. + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.connect(path) oattrs = tcgetattr(0) nattrs = tcgetattr(0) @@ -86,7 +95,14 @@ def connect(host,port): __send_to_sock(sock) if __name__ == '__main__': - if len(sys.argv) != 3: - print sys.argv[0] + " " + argc = len(sys.argv) + if argc < 3 or argc > 4: + print >>sys.stderr, sys.argv[0], " []" sys.exit(1) - connect(str(sys.argv[1]),int(sys.argv[2])) + host = sys.argv[1] + port = int(sys.argv[2]) + if argc > 3: + path = sys.argv[3] + else: + path = None + connect(host, port, path=path) diff --git a/tools/python/xen/web/unix.py b/tools/python/xen/web/unix.py index d82ed0a6c3..7381816031 100644 --- a/tools/python/xen/web/unix.py +++ b/tools/python/xen/web/unix.py @@ -1,6 +1,7 @@ import sys import socket import os +import os.path from connection import * from protocol import * @@ -15,18 +16,22 @@ class UnixListener(SocketListener): self.path = path def createSocket(self): - try: - os.unlink(self.path) - except SystemExit: - raise - except Exception, ex: - pass + pathdir = os.path.dirname(self.path) + if not os.path.exists(pathdir): + os.makedirs(pathdir) + else: + try: + os.unlink(self.path) + except SystemExit: + raise + except Exception, ex: + pass sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.bind(self.path) return sock def acceptConnection(self, sock, protocol, addr): - return UnixServerConnection(sock, protocol, addr, self) + return UnixServerConnection(sock, protocol, self.path, self) class UnixClientConnection(SocketClientConnection): diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 7495248753..557c18ecdd 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -324,7 +324,7 @@ class Daemon: xroot = XendRoot.instance() log.info("Xend Daemon started") self.createFactories() - self.listenEvent(xroot) + event.listenEvent(self) self.listenChannels() servers = SrvServer.create() self.daemonize() @@ -340,11 +340,6 @@ class Daemon: def createFactories(self): self.channelF = channel.channelFactory() - def listenEvent(self, xroot): - port = xroot.get_xend_event_port() - interface = xroot.get_xend_address() - return event.listenEvent(self, port, interface) - def listenChannels(self): def virqReceived(virq): print 'virqReceived>', virq diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py index 1cd1bb5df0..f366904d56 100755 --- a/tools/python/xen/xend/server/console.py +++ b/tools/python/xen/xend/server/console.py @@ -19,7 +19,7 @@ from messages import * from params import * class ConsoleProtocol(protocol.Protocol): - """Asynchronous handler for a console TCP socket. + """Asynchronous handler for a console socket. """ def __init__(self, console, id): @@ -36,10 +36,16 @@ class ConsoleProtocol(protocol.Protocol): self.loseConnection() return else: + if len(self.addr) == 2: + host = str(self.addr[0]) + port = str(self.addr[1]) + else: + host = 'localhost' + port = str(addr) log.info("Console connected %s %s %s", - self.id, str(self.addr[0]), str(self.addr[1])) + self.id, host, port) eserver.inject('xend.console.connect', - [self.id, self.addr[0], self.addr[1]]) + [self.id, host, port]) def dataReceived(self, data): if self.console.receiveInput(self, data): @@ -50,7 +56,6 @@ class ConsoleProtocol(protocol.Protocol): return len(data) def connectionLost(self, reason=None): - print 'ConsoleProtocol>connectionLost>', reason log.info("Console disconnected %s %s %s", str(self.id), str(self.addr[0]), str(self.addr[1])) eserver.inject('xend.console.disconnect', @@ -60,22 +65,7 @@ class ConsoleProtocol(protocol.Protocol): def loseConnection(self): self.transport.loseConnection() -class ConsoleFactory(protocol.ServerFactory): - """Asynchronous handler for a console server socket. - """ - protocol = ConsoleProtocol - - def __init__(self, console, id): - #protocol.ServerFactory.__init__(self) - self.console = console - self.id = id - - def buildProtocol(self, addr): - proto = self.protocol(self.console, self.id) - proto.factory = self - return proto - -class ConsoleDev(Dev): +class ConsoleDev(Dev, protocol.ServerFactory): """Console device for a domain. Does not poll for i/o itself, but relies on the domain to post console output and the connected TCP sockets to post console input. @@ -96,7 +86,9 @@ class ConsoleDev(Dev): self.obuf = xu.buffer() self.ibuf = xu.buffer() self.channel = None - self.listener = None + self.listening = False + self.unix_listener = None + self.tcp_listener = None console_port = sxp.child_value(self.config, "console_port") if console_port is None: @@ -188,9 +180,15 @@ class ConsoleDev(Dev): try: self.lock.acquire() self.status = self.STATUS_CLOSED + self.listening = False if self.conn: self.conn.loseConnection() - self.listener.stopListening() + if self.tcp_listener: + self.tcp_listener.stopListening() + self.tcp_listener = None + if self.unix_listener: + self.unix_listener.stopListening() + self.unix_listener = None finally: self.lock.release() @@ -201,16 +199,28 @@ class ConsoleDev(Dev): self.lock.acquire() if self.closed(): return - if self.listener: + if self.listening: pass else: + self.listening = True self.status = self.STATUS_LISTENING - cf = ConsoleFactory(self, self.id) - interface = xroot.get_console_address() - self.listener = reactor.listenTCP(self.console_port, cf, interface=interface) + if xroot.get_xend_unix_server(): + path = '/var/lib/xend/console-%s' % self.console_port + self.unix_listener = reactor.listenUNIX(path, self) + if xroot.get_xend_http_server(): + interface = xroot.get_console_address() + self.tcp_listener = reactor.listenTCP(self.console_port, self, interface=interface) finally: self.lock.release() + def buildProtocol(self, addr): + """Factory function called to create the protocol when a connection is accepted + by listenTCP. + """ + proto = ConsoleProtocol(self, self.id) + proto.factory = self + return proto + def connect(self, addr, conn): """Connect a TCP connection to the console. Fails if closed or already connected. diff --git a/tools/python/xen/xend/server/event.py b/tools/python/xen/xend/server/event.py index ebd4d6fd51..ce76c149b0 100644 --- a/tools/python/xen/xend/server/event.py +++ b/tools/python/xen/xend/server/event.py @@ -11,7 +11,7 @@ from xen.xend import EventServer eserver = EventServer.instance() from xen.xend.XendError import XendError -from xen.xend import XendRoot +from xen.xend import XendRoot; xroot = XendRoot.instance() DEBUG = 1 @@ -165,7 +165,7 @@ class EventProtocol(protocol.Protocol): def op_log_stderr(self, name, v): mode = v[1] - logging = XendRoot.instance().get_logging() + logging = xroot.get_logging() if mode == 'on': logging.addLogStderr() else: @@ -181,21 +181,23 @@ class EventProtocol(protocol.Protocol): import controller controller.DEBUG = (mode == 'on') -class EventFactory(protocol.Factory): +class EventFactory(protocol.ServerFactory): """Asynchronous handler for the event server socket. """ - protocol = EventProtocol - service = None def __init__(self, daemon): - #protocol.Factory.__init__(self) + #protocol.ServerFactory.__init__(self) self.daemon = daemon def buildProtocol(self, addr): - proto = self.protocol(self.daemon) - proto.factory = self - return proto + return EventProtocol(self.daemon) -def listenEvent(daemon, port, interface): +def listenEvent(daemon): factory = EventFactory(daemon) - return reactor.listenTCP(port, factory, interface=interface) + if xroot.get_xend_unix_server(): + path = '/var/lib/xend/event-socket' + reactor.listenUNIX(path, factory) + if xroot.get_xend_http_server(): + port = xroot.get_xend_event_port() + interface = xroot.get_xend_address() + reactor.listenTCP(port, factory, interface=interface) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index bd8f81ae3e..82fd0b7a22 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -593,7 +593,8 @@ def main(argv): else: (dom, console) = make_domain(opts, config) if opts.vals.console_autoconnect: - console_client.connect('localhost', console) + path = "/var/lib/xend/console-%s" % console + console_client.connect('localhost', console, path=path) if __name__ == '__main__': main(sys.argv) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index a3fb9c75f3..e1494bc3a1 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -644,7 +644,8 @@ class ProgConsole(Prog): self.err("No console information") port = sxp.child_value(console, "console_port") from xen.util import console_client - console_client.connect("localhost", int(port)) + path = "/var/lib/xend/console-%s" % port + console_client.connect("localhost", int(port), path=path) xm.prog(ProgConsole) -- 2.30.2